%% -*- mode: nitrogen -*-
%%@author Group 3
%%@version 0.8
%%@copyright Group 3 2011

-module (index).
-compile(export_all).
-include_lib("nitrogen/include/wf.hrl").
-include("records.hrl").

main() -> #template { file="./site/templates/index.html" }.

% Sends the connected user to the loggin site. 

redirect() ->
	case wf:user() of
		undefined ->
			wf:redirect("/login");
		_ -> ""
	end.

% Generate the title for the site.

title() -> 
	[
	"Pronection"
	].

% Generate the body for the site.

body() -> 
    [
            #panel { id=projectLabelPlaceHolder },
            #p{},
            #panel { id=placeholder },
            #panel { id=scriptPlaceholder }
    ].

% Generate a header with information about what project your in and shows what user your logged in to.      

userPanel() ->
	#panel {class="userPanelContainer", id=userPanel, body=
		[
		#panel {class="userPanelLeft", id=userPanelLeft, body=[
		#panel {id=projectIDPanel},
		#link {text="?", postback=playGame},
		"<img id='logga' src=/images/pronection-smalllogo.png>"]},
		#panel {class="userPanelRight", id=userPanelRight, body=[wf:user(), " | ",
			#link {text="Logout", postback=logout}
			]}
		]}.

%% Retrieves a list of all projects and then calls printProjectList to print it as html
%%Spec listProjects() -> any()

listProjects() ->
	erlang:set_cookie(node(), '1234567890'),
	{pronection_server, pronection_server@hamberg.it.uu.se} ! {listProjects, self()},
		receive
			{ok, ProjectList, _} ->
				#sortblock {
  				class=projectsortblock, 
  				group=projectsortblock, 
  				style="", 
  				connect_with_groups=[trash], 
  				tag=projectsortblock, 
  				items=[printProjectList(ProjectList)]
  				}	
		end.

%% Prints out html links of all the projects
%%Spec printProjectList(ProjectList) -> string

printProjectList([])-> 
	"";
printProjectList([H|T]) ->
	[
		#sortitem {tag=(element(1,H)), body=
  		[
  		#link { text=element(1,H), postback={switchProject, element(2,H), element(1,H)}}
  		]},
		printProjectList(T)
	].
	
% Creates a form for adding a task
%%Spec addTask() ->  any()

addTask() ->
	[
		#label { text="Add Task" },
		"<span class='tasklabel'>Title</span>",
        #textbox { id=addTaskName, style="margin: 0px;padding:0px;"},
        "<span class='taskdesc'>Description</span>",
        #textarea { id=addTaskDesc, text="", style="margin: 0px;padding:0px;" },
        #button { id=addTaskButton, text="Add", postback=addTask },
        "<div id='trash'>
        <br>",
  		#sortblock {
  			class=trash, 
  			group=trash, 
  			style="height:250px; background-image: url('/images/trashcan.gif'); background-repeat: no-repeat;", 
  			connect_with_groups=[waiting,inprogress,done], 
  			tag=trash, 
  			items=[]
  			},
   		"</div>"
	].

% Creates a form for adding a project
%Spec addProject() -> any()

addProject() ->
	[
		#label { text="Add new project" },
        #textbox { id=addProjectName },
        #button { id=addProjectButton, text="Add", postback=addProject }
	].
  
% Loads all the queues
%Spec loadQueues({Waiting,Busy,Done}) -> any()
%where
%	Waiting -> list
% 	Busy	-> list
%	Done	-> list
    
loadQueues({Waiting,Busy,Done}) ->
	[
	% Waiting queue
	"<div id='waiting'>
		<b>Waiting</b><br>
		<hr color='#ffaaaa'>",	
  		#sortblock {
  			class=waiting, 
  			group=waiting, 
  			style="padding-bottom: 10px", 
  			connect_with_groups=[inprogress,done,trash], 
  			tag=waiting, 
  			items=[printSortItems(Waiting, waiting)]
  			},
   		"</div>",
   		
	
	% Busy queue
	"<div id='inprogress'>
		<b>In Progress</b><br>
		<hr color='#ffeb98'>",	
    	#sortblock { 
    		class=inprogress, 
    		group=inprogress, 
    		style="padding-bottom: 10px", 
    		connect_with_groups=[waiting,done,trash], 
    		tag=inprogress, 
    		items=[printSortItems(Busy, busy)]
    		},
   		"</div>",
   		
   	% Done queue
   	"<div id='done'>
		<b>Done</b><br>
		<hr color='#99ff99'>",	
    	#sortblock { 
    		class=done, 
    		group=done, 
    		style="padding-bottom: 10px", 
    		connect_with_groups=[waiting,inprogress,trash], 
    		tag=done, items=[printSortItems(Done, done)]
    		},
    	"</div>"	
    ].
    
% prints task description
printDesc(D, Type) ->
	[
		element(2,D),
		case Type of
			waiting ->
				[
				"<br /><b>Creator: </b>",
				 element(4, D)
				];
			busy ->
				[
				"<br /><b>Working: </b>",
				element(3, D),
				"<br /><b>Creator: </b>",
				 element(4, D)
				 ];
			done ->
				[
				"<br /><b>Completed by: </b>",
				element(3, D),
				"<br /><b>Creator: </b>",
				 element(4, D)
				 ]
			end
	].    
 
%element(1,H) = Namnet(Sträng), element(2,H)=Taskstatus, element(3,H)=ID
%Spec printSortItems(list) -> string

printSortItems([],_) ->
    "";
printSortItems([H|T], Type) ->
	Event = #event { target=integer_to_list(element(6,H)), type=click },
	[
  		#sortitem {tag=element(6,H), body=
  		[
  			#panel {id=integer_to_list(element(6,H)), body=[
  			#link { body=#image { image="/images/arrow.gif" }, actions=Event#event { 
            actions=#toggle{ effect=drop, options=[{direction, up}], speed=500}}},
        	" ",
        	element(1,H),
  			#panel {style='display: none;', class=description, id=integer_to_list(element(6,H)), body=printDesc(H,Type)}
  			]}
  		]},	
  		printSortItems(T, Type)
   	].


%Doc List all tasks in the project projectID
%Spec listsTasks(ProjectID) -> any()
%where
% 	ProjectID -> integer
%Spec sort_event(_Tag, Items) -> atom
% where
%		_Tag 	->
%		Items 	->

listTasks(ProjectID) ->
	erlang:set_cookie(node(), '1234567890'),
    {list_to_atom(hd(io_lib:format("~w",[ProjectID]))), pronection_server@hamberg.it.uu.se} ! {listTasks, self()},    
 		receive
			{ok,TaskList, _} ->
				TaskList;
			{error, _, _} ->
				["Error"]
     	end.   	

%% Triggas varje gång någon flyttar en task 
%% Variables: _Tag = Den flyttade tasken
%% 			 Items = Listan på nya ordningen av tasksen
sort_event(_Tag, Items) ->
	erlang:set_cookie(node(), '1234567890'),
	case (_Tag) of 
	trash ->
		case is_list(hd(Items)) of
		true ->
			{pronection_server, pronection_server@hamberg.it.uu.se} ! {deleteProject, hd(Items), self()},
			receive
				{ok, _ } ->
					io:format("Project was deleted");
				{error, Mes, _} ->
					io:format("~s ~n",[Mes])
			end;
		false ->
			{(wf:to_atom(wf:cookie("projectID"))), pronection_server@hamberg.it.uu.se} ! {deleteTask, hd(Items), self()},    
 			receive
				{ok, _} ->
					io:format("Task was deleted");
					
					%wf:send_global(notificationsRoom, {update, wf:q(projectIDTextbox)});
				{error, Mes, _} ->
					io:format("~s ~n",[Mes])
     		end
     	end;		
	projectsortblock ->
		"";
	_ ->
    	{(wf:to_atom(wf:cookie("projectID"))), pronection_server@hamberg.it.uu.se} ! {sortTasks, _Tag, Items, wf:user(), self()},    
 			receive
 				{ok, update, _} ->
 					io:format("~nComet update, telling everyone in room ~s to update!", [wf:cookie("projectID")]),
 					wf:update(placeholder, loadQueues(listTasks(wf:to_integer(wf:cookie("projectID"))))),
 					% Tell everyone in the same room as me to update
 					wf:send_global(wf:cookie("projectID"), {update});
				{ok, origin, _} ->			 
					"";
				{error, Mes, _} ->
					io:format("~s ~n",[Mes]),
					wf:update(placeholder, loadQueues(listTasks(wf:to_integer(wf:cookie("projectID")))))
     		end
     end,
   	 ok.

% Adds a new task to the current project
% Spec event(addTask) -> any
% where
%	addTask -> atom()

event(addTask) ->
	Text = wf:q(addTaskName),
	Desc = wf:q(addTaskDesc),
	erlang:set_cookie(node(), '1234567890'),
	{(wf:to_atom(wf:cookie("projectID"))), pronection_server@hamberg.it.uu.se} ! {addTask, Text, Desc, wf:user(),self()},
		receive
			{ok, _} ->
				io:format("Task was added to project ~s ~n", ["project1"]),
				wf:update(placeholder, loadQueues(listTasks((wf:to_integer(wf:cookie("projectID"))))));
			{error, _,_} ->
				io:format("Error when adding Task ~n"),
				wf:wire(#alert { text="A task with that name already exists" })
		end;

% Adds a new project	
%Spec event(addProject) -> any()
%where
%	addProject -> atom()
	
event(addProject) ->
	Text = wf:q(addProjectName),
	case length(Text) == 0 of
	true ->
		wf:wire(#alert { text="You have to enter a name for the project you want to add" });
	_	 ->	
		erlang:set_cookie(node(), '1234567890'),
		{pronection_server, pronection_server@hamberg.it.uu.se} ! {addProject, Text, self()},
			receive
				{ok, _} ->
					wf:insert_top(scriptPlaceholder, "<script type='text/Javascript'>location.reload()</script>");
				{error,_, _} ->
					io:format("Error when adding Task ~n"),
					wf:wire(#alert { text="You have to enter a name for the project you want to add" })
			end
	end;

%
%Spec event({switchProject,ProjectID,ProjectName}) -> atom()
%where
%	switchProject->	atom()
%	ProjectID -> 	integer
% 	ProjectName ->	string
		
event({switchProject, ProjectID, ProjectName}) ->
	io:format("~nTelling room ~s to exit, I'm joining room: ~s~n", [wf:cookie("projectID"), integer_to_list(ProjectID)]),
	wf:send_global(wf:cookie("projectID"), {exit, (ProjectID)}),
	timer:sleep(100),
	io:format("Joining the new room: ~w~n", [ProjectID]),
	wf:comet_global(fun() -> notificationsLoop(integer_to_list(ProjectID)) end, integer_to_list(ProjectID)),
	
    wf:update(placeholder, loadQueues(listTasks(ProjectID))),
    wf:update(projectLabelPlaceHolder, "<h1>"++ProjectName++"</h1>"),
    wf:cookie("projectID", integer_to_list(ProjectID)),
    wf:cookie("projectName", ProjectName),
    ok;

% Trigger the logout event 
%Spec event(logout) -> atom()
%where
%	logout -> atom() 
    
event(logout) ->
	wf:clear_session(),
    wf:redirect("/");

% Trigger the secret game for thouse long office houers
%Spec event(playGame) -> any()
%where 
%	playGame -> atom()

event(playGame) ->
	wf:redirect("javascript:var%20s%20=%20document.createElement('script');s.type='text/javascript';document.body.appendChild(s);s.src='http://yourjavascript.com/12512268610/asteroids.min.js';void(0)");

%
%Spec event(_) -> atom()

event(_) -> 
	ok.


% 
%Spec notificationsLoop() -> any(


notificationsLoop(ProjectID) ->
    receive 
        'INIT' ->
            io:format("Comet has spawned!~n");
        {update} ->
        	wf:update(placeholder, loadQueues(listTasks(wf:to_integer(ProjectID)))),
        	io:format("~n I received a call to update the content of project: ~s", [ProjectID]),
        	wf:flush();
        {exit, OldProjectID} ->
        	case ProjectID==OldProjectID of
        	true ->
        		io:format("My project ID is: ~w, I received: ~w, I shouldn't exit comet~n", [ProjectID, OldProjectID]),
        		wf:flush();
        	false ->
        		io:format("I'm exiting project ~s~n", [ProjectID] ),
        		wf:flush(),
        		exit(done)  
        	end 		        
    end,
    notificationsLoop(ProjectID). 
